<?php

/**
 * 余外-火凤凰 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shophuofenghuang;
use App\Model\PssModel\ServiceConfig;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;   

class ShophuofenghuangApiClient
{
    private $account  = 'Shophuofenghuang';
    protected $config;
    protected $RouteMap = [
        'createOrder'   => '/base-boot/jeewms/externalApi/declPush',
        'cancelOrder'   => '/base-boot/jeewms/externalApi/orderCancel',
    ];
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', -1);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //商品下单组
        $wmOmNoticeIList = $OrderItem =[];
        $productAmt     = $TaxAmt =  $total_count = 0 ;
        foreach ($params['orderGoods'] as $key => $item ) 
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,2);
            
            //含税税率
            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            //不含税价格
            $not_tax_price      = bcdiv((string)$singleGoodsPrice, (string)$tax_rate,3);
            $not_tax_price      = ceil(bcmul((string)$not_tax_price,(string)'100',1));
            $not_tax_price      = bcdiv((string)$not_tax_price,'100',2);
            
            //税金
            $singleGoodsTax     = bcsub((string)$singleGoodsPrice, (string)$not_tax_price,3);
            
            //单个商品总税金
            $totalGoodsTax  = bcmul((string)$singleGoodsTax,(string)$buyAcount,2); 
            
            //单个商品总不含税价格
            $totalGoods     = bcmul((string)$not_tax_price,(string)$buyAcount,2);
            //商品组
            $wmOmNoticeIList[] = [
                "cusCode"       => $this->config["cusCode"],
                "goodsName"     => $item["goods_name"],
                "barcode"       => $item["barcode"],
                "goodsUnitPrice"=> (float)$not_tax_price,
                "baseGoodscount"=> (string)$buyAcount,
                "goodsQua"      => (string)$buyAcount,
                "goodsId"       => (string)$item['supplier_skucode'],
            ];
            $OrderItem[] = [
                "sku_id"        => $item['supplier_skucode'],
                "goods_name"    => $item["goods_name"],
                "goods_order"   => (int)$key+1,
                "qty"           => (int)$buyAcount,
                "declare_qty"   => (int)$buyAcount,
                "bar_code"      => $item["barcode"],
                "total_price"   => (float)$totalGoods,
                "unit_price"    => (float)$not_tax_price,
                "tax_fee"       => (float)$totalGoodsTax,
            ];
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
            $TaxAmt = bcadd((string)$TaxAmt,(string)$totalGoodsTax,2);
            //总购买数
            $total_count = bcadd((int)$total_count,(int)$buyAcount,2);
        }

        //实际下单金额 
        $real_total_money = $orderInfo['real_total_money'];
        //订单总金额 = 不含税商品总金额 + 总税费 + 运费 - 优惠金额
        $ActualPaidAmt  = bcadd((string)$productAmt,(string)$TaxAmt,2);
        $ActualPaidAmt  = bcadd((string)$ActualPaidAmt,(string)$deliver_money,2);
        //优惠金额
        $discount_money = bcsub((string)$ActualPaidAmt,$real_total_money,2);
        
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time(); 
        $payTime        = date("Y-m-d H:i:s",$pay_time); 
        //支付时间从秒时间戳转为毫秒时间戳
        $pay_time       = bcmul((int)$pay_time,1000);

        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        
        //获取上游供应商支付方式路由
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyName = $apply_extends['payCommanyName'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        $payCommanyName = $order['payCommanyName'] ? $order['payCommanyName'] : $payCommanyName;
        $pay_value      = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$PayCompanyCode}】未映射，请联系云仓管理员处理");
        } 
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        
        //创建订单数据
        $wmsUserOrderPushData = [
            'order_id'          => $orderInfo['supplier_dsn'],
            'payment_id'        => $pay_sn,
            'pay_info'          => [
                'pay_amount'            => (float)$real_total_money,
                'pay_currency_code'     => "CNY",
                'pay_rmb_amount'        => (float)$real_total_money,
                'payment_company_name'  => $payCommanyName,
                'payment_company_code'  => $PayCompanyCode,
                'platform_id'           => $enterpriseNum,
                'platform_name'         => $enterpriseName,
                'payment_id'            => $pay_sn,
            ],
            'pay_method_id'     => (int)$pay_value,
            'platform_code'     => $enterpriseNum,
            'platform_name'     => $enterpriseName,
            'specified_packing' => (string)$binfo["is_order_package"],
            'purchaser_acount'  => $orderInfo['buyer_phone'],
            'buyer_name'        => $orderInfo['buyer_realname'],
            'purchaser_tel'     => $orderInfo['buyer_phone'],
            'coupon_amount'     => (float)$discount_money,
            'total_count'       => (int)$total_count,
            'order_create_time' => date("Y-m-d H:i:s",time()),
            'pay_time'          => $payTime,
            'receiver_id'       => $orderInfo['buyer_idcard'],
            'receiver_province' => $orderInfo['province'],
            'receiver_city'     => $orderInfo['city'],
            'receiver_county'   => $orderInfo['district'],
            'receiver_address'  => $orderInfo['receive_address'],
            'receiver_name'     => $orderInfo['receive_name'],
            'receiver_mobile'   => $orderInfo['recveive_phone'],
            'remark'            => $orderInfo['order_remark'],
            'order_goods_amount'=> (float)$productAmt,
            'order_total_amount'=> (float)$real_total_money,
            'order_tax_amount'  => (float)$TaxAmt,
            'order_items'       => $OrderItem,
            'fee_info'          => [
                'deduction_amount'      => (float)$discount_money,
                'deduction_note'        => (string)$discount_money >0 ? $discount_money : "无",
                'freight'               => (float)$deliver_money,
                'insurance'             => 0.00,
                'tax'                   => (float)$TaxAmt,
            ],
            'fee_amount'      => (float)$deliver_money,
        ];
        $data = [
            'cusCode'               => $this->config['cusCode'],
            'delvMember'            => $orderInfo['receive_name'],
            'delvMobile'            => $orderInfo['recveive_phone'],
            'delvAddr'              => $orderInfo['receive_address'],
            'delvData'              => bcmul((int)time(),1000),
            'outStoreCode'          => $this->config['outStoreCode'],
            'payTime'               => $pay_time,
            'imCusCode'             => $orderInfo['supplier_dsn'],
            'orderPayAmount'        => (float)$real_total_money,
            'wmOmNoticeIList'       => $wmOmNoticeIList,
            'wmsUserOrderPushData'  => $wmsUserOrderPushData,
        ];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
   
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] ) 
    {
        $data = [
            'order_id'          => (string)$params['supplierOrder']['supplier_dsn'],
        ];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
    // 获取当前毫秒时间戳
    function getMillisecondsTimestamp() {
        $microtime = microtime();
        list($seconds, $microseconds) = explode(' ', $microtime);
        $milliseconds = round($microseconds * 1000);
        return (int)($seconds . $milliseconds);
    }
    
    /**
     * 加签
     * @param array $param
     */
    protected function getSign( array $param = [] )
    {
        //公钥密文;
       // $hex_str = "30819f300d06092a864886f70d010101050003818d0030818902818100bcb5ca5da35a15050c27f07a0af74b1e6abeae4e214fff0015a81024d909cd9864ccb2c94be9984e3fef22b807b438c13fb9cbe428d33ed4e2a05dfe4e05b783c56c0d638385f9ba724bfad0f38dd576587b70161f59a9533c05c18e43e669a87ee85aa6cbb8f33a95953a0804c6de99a20293f16a3345e27401ea7c3eb204930203010001";
        //私钥密文
       // $hex_str = '30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100bcb5ca5da35a15050c27f07a0af74b1e6abeae4e214fff0015a81024d909cd9864ccb2c94be9984e3fef22b807b438c13fb9cbe428d33ed4e2a05dfe4e05b783c56c0d638385f9ba724bfad0f38dd576587b70161f59a9533c05c18e43e669a87ee85aa6cbb8f33a95953a0804c6de99a20293f16a3345e27401ea7c3eb2049302030100010281805acfd8ecaad984d802fb8d5c0dbee7a5619515687fdb7149672293724807d1aa8e877b5a276fe85d6fa2f2c040e4d79317c99f76d2b6a5bbe8bb67c02367d8e179fc801c71cf8775940d40882f96fa4c8234de3727c9006d80c414cf9c916f540b0c1e6f7b2ccb58d0b55e3bfaf01cc490f3638fd4828ee195e2d091e79eb951024100f444f031c5a827a7e8c7412689adf8bbed6ce46e86e7e76e81b644f1d76c4b52f5b47229de18bb9dbdd06e39492ee4367700189c1432613c44e88d560fb51dcd024100c5c5cdea04cf9aee73bdccf4e9841714286323b4aa0661a6e5c5f7feade4a2149441cf19c592c983a589be77da63b8d3d218268800bcc32c3575af62fefa4bdf0241009df37e061133dd00bc8b2bdbc9a78f71a5e3860ada7d56afa47cc2344802a4ea6e2b52af340876395826514005cca691797dbc6c20bb3b1907ce00a6a7dd8bf902401e16f93c389d29724c13bd8229a11a2dcbf341747445e247953fe87a4c14b400338a4bab1d1f371f9b68f89c9d927c8565ba9cea264a91db410af5b3371df7bb02405f90131def81916edbb47c37ef8fc32b0794bb40928c248979eca867887c5c770455291ec621639bae40dc335bcbd336216f6b7421fc489c7eacb8bff76db91d';
        $str  =  hex2bin($this->config["yc_private_key"]);
        $str = base64_encode($str);
        $private_key ="-----BEGIN PRIVATE KEY-----\n".
            wordwrap($str, 64, "\n", true).
            "\n-----END PRIVATE KEY-----";
        $key = openssl_pkey_get_private($private_key);
        openssl_sign(json_encode($param), $signature, $key);
        openssl_free_key($key);
        return bin2hex($signature); 
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    
    public function execute( $param = [] )  
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method = $param['method'];
        $sign=$this->getSign($param["data"]);
        $url = $this->config['baseurl'].$this->RouteMap[$method];
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [
                    "Content-Type: application/json;charset=UTF-8",
                    "sign:{$sign}",
                ],
        
            ],
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        
        if(isset($resHttp['success']) && $resHttp['success'] == true && isset($resHttp['error_code']) && $resHttp['error_code'] == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        
        return Normal::returnCode(Normal::FAIL,$res ? $res : "接口请求异常");
    }
}